﻿/*********************************************
 * Author: resaberonjr
 * DateWritten: 09/2011
 *********************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity;
using System.Linq.Expressions;
using RootBaseFramework.Domain;

namespace RootBaseFramework.Infra.Data
{
    public abstract class RepositoryBase<TEntity, TKey> : IRepository<TEntity, TKey>
        where TEntity : class
    {
        private IUnitOfWork _unitOfWork;



        // private DbSet<TEntity> _set;

        public IDbSet<TEntity> Set
        {
            get
            {
                //return _set; 
                return _unitOfWork.Context.Set<TEntity>();
            }
        }


        public RepositoryBase(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
            // _set = unitOfWork.Context.Set<TEntity>(); 

        }

        public virtual void Add(TEntity entity)
        {
            //_set.Add(entity);
            _unitOfWork.Context.Set<TEntity>().Add(entity);
        }

        public virtual void Update(TEntity entity)
        {
            _unitOfWork.Context.Entry<TEntity>(entity).State = System.Data.EntityState.Modified;
        }

        public virtual void Remove(TEntity entity)
        {
            //_set.Remove(entity);  
            _unitOfWork.Context.Set<TEntity>().Remove(entity);
        }

        protected virtual void Save()
        {
            _unitOfWork.Commit();
        }

        public TEntity Find(TKey entityId)
        {
            //return _set.Find(entityId);
            return _unitOfWork.Context.Set<TEntity>().Find(entityId);
        }

        public IEnumerable<TEntity> FindAll(Expression<Func<TEntity, bool>> filter)
        {
            //return _set.Where(filter);
            return _unitOfWork.Context.Set<TEntity>().Where(filter);
        }

        public TEntity Find(Expression<Func<TEntity, bool>> filter)
        {
            // return _set.Where(filter).SingleOrDefault(); 
            return _unitOfWork
                        .Context
                        .Set<TEntity>()
                        .SingleOrDefault();
        }

        public IEnumerable<TEntity> FindAll()
        {
            //return _set;
            return _unitOfWork
                        .Context
                        .Set<TEntity>();

        }

        public IEnumerable<TEntity> FindAll(int pageIndex, int pageSize)
        {
            //return _set.Skip(pageIndex * pageSize).Take(pageSize);
            return _unitOfWork
                        .Context
                        .Set<TEntity>()
                        .Skip(pageIndex * pageSize)
                        .Take(pageSize);
        }

        public IEnumerable<TEntity> FindAll(Expression<Func<TEntity, bool>> filter, int pageIndex, int pageSize)
        {
            //return _set.Where(filter).Skip(pageIndex * pageSize).Take(pageSize);
            return _unitOfWork
                        .Context
                        .Set<TEntity>()
                        .Where(filter)
                        .Skip(pageIndex * pageSize)
                        .Take(pageSize);

        }




        public virtual IEnumerable<TEntity> FindAll(bool includeChildren)
        {
            return FindAll();
        }

        public virtual IEnumerable<TEntity> FindAll(Expression<Func<TEntity, bool>> filter, bool includeChildren)
        {
            return FindAll(filter);
        }

        public virtual IEnumerable<TEntity> FindAll(int pageIndex, int pageSize, bool includeChildren)
        {
            return FindAll(pageIndex, pageSize);
        }

        public virtual IEnumerable<TEntity> FindAll(Expression<Func<TEntity, bool>> filter, int pageIndex, int pageCount, bool includeChildren)
        {
            return FindAll(filter, pageIndex, pageCount);
        }

    

        public int Count()
        {
            //return _set.Count();
            return _unitOfWork
                        .Context
                        .Set<TEntity>()
                        .Count();

        }

        public int Count(Expression<Func<TEntity, bool>> filter)
        {
            //return _set.Count(filter);
            return _unitOfWork
                        .Context
                        .Set<TEntity>()
                        .Count(filter);

        }

        //public int Count(Specification<TEntity> spec)
        //{
        //    return Count(spec.SatisfiedBy());
        //}

        //public virtual IEnumerable<TEntity> FindAll(Specification<TEntity> spec, bool includeChildren)
        //{
        //    return FindAll(spec);
        //}

        //public IEnumerable<TEntity> FindAll(Specification<TEntity> spec)
        //{
        //    //return _set.Where(spec.SatisfiedBy());
        //    return _unitOfWork
        //                .Context
        //                .Set<TEntity>()
        //                .Where(spec.SatisfiedBy());

        //}
    }
}
